﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace OPCDiffCore
{
    /// <summary>
    /// Differences in an OPC package part.
    /// </summary>
    public sealed class PartDiff : IEnumerable<DiffElement>
    {
        /// <summary>
        /// Part URI.
        /// </summary>
        public Uri PartUri { get; internal set; }

        /// <summary>
        /// Part content type.
        /// </summary>
        public string PartContentType { get; internal set; }

        /// <summary>
        /// Difference type.
        /// </summary>
        public DiffType DiffType { get; internal set; }

        /// <summary>
        /// Count the number of diff elements.
        /// </summary>
        public int Count
        {
            get { return diffCollection.Count; }
        }

        /// <summary>
        /// Store all DiffElement 
        /// </summary>
        private DiffElementCollection diffCollection = new DiffElementCollection();

        #region Constructors

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="uri">Part URI.</param>
        /// <param name="contentType">Part content type.</param>
        public PartDiff(Uri uri, string contentType)
        {
            this.PartUri = uri;
            this.PartContentType = contentType;
            this.DiffType = DiffType.Unchanged;
        }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="uri">Part URI.</param>
        /// <param name="contentType">Part content type.</param>
        /// <param name="diffType">Diff type.</param>
        public PartDiff(Uri uri, string contentType, DiffType diffType)
            : this(uri, contentType)
        {
            this.DiffType = diffType;
        }

        #endregion

        /// <summary>
        /// Adds the specified element.
        /// </summary>
        /// <param name="diffElement">The element to add.</param>
        public void Add(DiffElement diffElement)
        {
            if (diffElement == null)
                throw new ArgumentNullException("diffElement");

            diffCollection.Add(diffElement);
        }

        /// <summary>
        /// Removes the specified element.
        /// </summary>
        /// <param name="diffElement">The element to remove.</param>
        public void RemoveDiff(DiffElement diffElement)
        {
            if (diffElement == null)
                throw new ArgumentNullException("diffElement");

            diffCollection.Remove(diffElement);
        }

        /// <summary>
        /// Removes all the 
        /// </summary>
        /// <param name="actionType"></param>
        public void RemoveDiffByActionType(DiffType actionType)
        {
            Predicate<DiffElement> pred = new Predicate<DiffElement>(delegate(DiffElement elementToCheck)
            {
                return (elementToCheck.ActionType == actionType);
            });
            diffCollection.RemoveAll(pred);
        }

        #region IEnumerable<DiffElement> Members

        public IEnumerator<DiffElement> GetEnumerator()
        {
            return diffCollection.GetEnumerator();
        }

        IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return (IEnumerator)diffCollection.GetEnumerator();
        }

        #endregion
    }
}
